package com.monkeyboy.config;

/**
 * @Author Gavin
 * @date 2021.06.03 16:58
 */

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    /*
        授权码模式：
    localhost:9080/oauth/authorize?client_id=client1&response_type=code&scope=scope1&redirect_uri=http://www.baidu.com
     */

    /**
     * 密码模式换取token:
     * localhost:9080/oauth/token?client_id=client1&client_secret=123456&username=admin&password=123456&grant_type=password
     */


    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .exceptionHandling()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/system").hasAuthority("system")
                //本项目所需要的授权范围,这个scope是写在auth服务的配置里的
                .antMatchers("/test").access("#oauth2.hasScope('scope1')")
                .antMatchers("/allow").permitAll()

                .antMatchers("/**").authenticated()//其它的
                .and()
                //这个貌似是配置要不要把token信息记录在session中
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.csrf().disable();
    }

    /**
     * 基于远程校验，性能较低
     * 就是配置资源服务器获取到token后取授权服务器进行校验，每次校验都会请求授权服务器，所以性能比较低
     */
/*    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {

        //远程token验证, 普通token必须远程校验
        RemoteTokenServices tokenServices = new RemoteTokenServices();
        //配置去哪里验证token
        tokenServices.setCheckTokenEndpointUrl("http://127.0.0.1:8080/oauth/check_token");

        //配置组件的clientid和密码,这个也是在auth中配置好的
        tokenServices.setClientId("client1");
        tokenServices.setClientSecret("123456");

        resources
                //设置我这个resource的id, 这个在auth中配置, 这里必须一样
                .resourceId("resource1")
                .tokenServices(tokenServices)

                //这个貌似是配置要不要把token信息记录在session中
                .stateless(true);
    }*/

    /**
     * 基于jwt的校验
     */
    @Autowired
    private TokenStore tokenStore;
    @Autowired
    AuthenticationEntryPoint authExceptionEntryPoint;
    @Autowired
    AccessDeniedHandler customAccessDeniedHandler;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId("resource1").tokenStore(tokenStore).stateless(true);
        //自定义异常信息返回
        resources.authenticationEntryPoint(authExceptionEntryPoint)
                .accessDeniedHandler(customAccessDeniedHandler);

    }

}

